package com.lightsaber.trade.as.web.plansecond;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.convention.annotation.Namespace;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springside.modules.orm.Page;
import org.springside.modules.utils.web.struts2.Struts2Utils;

import com.lightsaber.trade.as.entity.category.CategoryNode;
import com.lightsaber.trade.as.entity.planning.Level2Planning;
import com.lightsaber.trade.as.entity.planning.Planning;
import com.lightsaber.trade.as.entity.planning.PlanningLevel;
import com.lightsaber.trade.as.entity.planning.PlanningStatus;
import com.lightsaber.trade.as.entity.planning.ProgrammePlanningItem;
import com.lightsaber.trade.as.service.category.CategoryNodeService;
import com.lightsaber.trade.as.service.category.CategoryService;
import com.lightsaber.trade.as.service.param.ParamService;
import com.lightsaber.trade.as.service.planning.Level2BreakDownService;
import com.lightsaber.trade.as.service.planning.Level2PlanningService;
import com.lightsaber.trade.as.service.planning.PlanningService;
import com.lightsaber.trade.as.service.planning.ProgrammePlanningItemService;
import com.lightsaber.trade.core.entity.BaseEntity;
import com.lightsaber.trade.core.web.BaseAction;

@Namespace("/plansecond")
public class PlanSecondAction extends BaseAction {
    private static final long serialVersionUID = -7076736990225879052L;
    private static final Logger log = LoggerFactory.getLogger(PlanSecondAction.class);

    public static final String SUCESSFULLY = "<Grid><IO Result='0'/></Grid>";

    @Autowired
    private transient Level2PlanningService level2Service;

    @Autowired
    private transient CategoryNodeService nodeService;
    @Autowired
    private transient CategoryService categoryService;
    @Autowired
    private transient PlanningService planningService;

    @Autowired
    private transient ParamService paramService;

    @Autowired
    private transient ProgrammePlanningItemService ppiService;
    @Autowired
    private transient Level2BreakDownService breakDownService;
    private Map<Integer, String> plannerYearMap;

    private Level2Planning level2Planning;

    @Value(value = "#{appProperties['level.2.plan.page.size']}")
    private String pageSize;

    private Page<Level2Planning> page;
    private boolean search;

    private String categoryId;
    private String level1Status;
    private String disciplineType;
    private String viewDetailData;
    private String categoryNodeId;
    private String programmeCode;
    private String searchByInService;

    private String programmePlanningItemId;

    private ProgrammePlanningItem ppi;

    private boolean canEdit;

    @Override
    public String execute() {
        return list();
    }

    public String list() {
        if (search) {
            if (page == null) {
                page = new Page<Level2Planning>(Integer.valueOf(pageSize));
            } else {
                page.setPageSize(Integer.valueOf(pageSize));
            }

            if (!page.isOrderBySetted()) {
                page.setOrderBy(BaseEntity.ID);
                page.setOrder(Page.ASC);
            }

            level2Service.findPage(level2Planning, page);
        } else {
            level2Planning = null;
        }
        // setPlannerYearMap(level2Service.getAllPlanningExercise());
        return SUCCESS;
    }

    public void getLevel1PlanningStatus() {
        Planning planning = planningService.findByCategoryIdAndPlanningLevel(categoryId,
                PlanningLevel.FirstLevel);
        Map<String, String> map = new HashMap<String, String>();
        if (planning != null) {
            map.put(PlanningLevel.FirstLevel.name(), planning.getStatus().getLabel());
        }
        Struts2Utils.renderJson(map);
    }

    @Override
    public String input() {
        level2Planning = level2Service.get(level2Planning.getId());
        Planning planning = planningService.findByCategoryIdAndPlanningLevel(level2Planning
                .getPlanning().getCategory().getId(), PlanningLevel.FirstLevel);
        if (planning != null) {
            setLevel1Status(planning.getStatus().getLabel());
        }
        return INPUT;
    }

    public String save() throws Exception {
        level2Service.save(level2Planning);
        addActionMessage(getText(PROCESSED_SUCCESS));
        return input();
    }

    public String loadLevel2TreeByLevel1Status() {
        String str = level2Service.loadLevel2TreeByLevel1Status(level2Planning.getId(),
                programmeCode);
        log.info("action loadLevel2TreeByLevel1Status :{} ", str);
        Struts2Utils.renderXml(str);
        return null;
    }

    // 7. For Planning Exercise and 1st Level Planning, in which status can be
    // deleted/Edit?
    // - Waiting for Submission (Delete: Y / Edit: Y)
    // - Waiting for Endorsement. (Delete: N /Edit: N)
    // - Endorsed (Delete: N / Edit: N)
    // - Not Endorsed (Delete: Y /Edit: Y)
    // - Rejected (Delete: Y / Edit: Y)
    // - Unlocked (Delete: N/ Edit: Y only for the unlocked)

    public String viewDetail() {
        setDisciplineType(disciplineType);
        setCategoryNodeId(categoryNodeId);

//        if (StringUtils.isBlank(searchByInService)) {
//            searchByInService = paramService.getPreEmploymentInServiceList().get(0).getCode();
//        }
        setSearchByInService(searchByInService);
        Level2Planning level2 = level2Service.findById(level2Planning.getId());
        String status = level2.getPlanning().getStatus().name();
        if (status.equals(PlanningStatus.WaitingForEndorsement.name())
                || status.equals(PlanningStatus.Endorsed.name())) {
            setCanEdit(false);
        } else {
            setCanEdit(true);
        }

        setLevel2Planning(level2);
        if (StringUtils.isNotBlank(categoryNodeId)) {
            CategoryNode node = nodeService.findById(categoryNodeId);
            if (node != null && node.getLevel2status() != null) {
                if (!node.getLevel2status().equals(PlanningStatus.WaitingForEndorsement)) {
                    setCanEdit(true);
                }
            }
        }

        Planning planning = planningService.findByCategoryIdAndPlanningLevel(level2.getPlanning()
                .getCategory().getId(), PlanningLevel.FirstLevel);
        if (planning != null) {
            setLevel1Status(planning.getStatus().name());
        }

        return "view-detail";
    }

    public String getViewDetail() {
        viewDetailData = level2Service.getViewDetail(disciplineType, level2Planning.getId(),
                categoryNodeId, searchByInService, false);
        viewDetailData = viewDetailData
                .replace("(Break Down)", "&lt;br/&gt; Break &lt;br/&gt;Down");
        // viewDetailData = viewDetailData.replace("(sum", "\"sum");
        // viewDetailData = viewDetailData.replace("))", ")\"");
        Struts2Utils.renderXml(viewDetailData);
        return null;

    }

    public String saveViewDetail() {
        try {
            level2Service.saveViewDetail(viewDetailData);
            Struts2Utils.renderXml(SUCESSFULLY);
        } catch (Exception e) {
            log.error("exceptio : ", e);
            addActionError(e.getMessage());
        }
        return null;
    }

    public void confirmForDetail() throws Exception {
        log.info("confirm :{}", "successfully");
        level2Service.confirmDetail(level2Planning.getId(), categoryNodeId);
    }

    public String turnToBreakDownPage() {
        ppi = ppiService.get(programmePlanningItemId);
        setPpi(ppi);
        return "break-down";
    }

    public String saveBreakDown() {

        breakDownService.saveBreakDownList(ppi);
        setPpi(ppiService.get(ppi.getId()));
        addActionMessage(getText(PROCESSED_SUCCESS));
        return "break-down";

    }

    public String turnToInputPageTree() {
        setLevel2Planning(level2Planning);
        setProgrammeCode(programmeCode);
        return "input-page-tree";
    }

    public Map<Integer, String> getPlannerYearMap() {
        return plannerYearMap;
    }

    public void setPlannerYearMap(final Map<Integer, String> plannerYearMap) {
        this.plannerYearMap = plannerYearMap;
    }

    public Level2Planning getLevel2Planning() {
        return level2Planning;
    }

    public void setLevel2Planning(final Level2Planning level2Planning) {
        this.level2Planning = level2Planning;
    }

    public Page<Level2Planning> getPage() {
        return page;
    }

    public void setPage(final Page<Level2Planning> page) {
        this.page = page;
    }

    public boolean isSearch() {
        return search;
    }

    public void setSearch(final boolean search) {
        this.search = search;
    }

    public PlanningService getPlanningService() {
        return planningService;
    }

    public String getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(final String categoryId) {
        this.categoryId = categoryId;
    }

    public String getLevel1Status() {
        return level1Status;
    }

    public void setLevel1Status(final String level1Status) {
        this.level1Status = level1Status;
    }

    public String getDisciplineType() {
        return disciplineType;
    }

    public void setDisciplineType(final String disciplineType) {
        this.disciplineType = disciplineType;
    }

    public String getViewDetailData() {
        return viewDetailData;
    }

    public void setViewDetailData(final String viewDetailData) {
        this.viewDetailData = viewDetailData;
    }

    public String getCategoryNodeId() {
        return categoryNodeId;
    }

    public void setCategoryNodeId(final String categoryNodeId) {
        this.categoryNodeId = categoryNodeId;
    }

    public String getProgrammeCode() {
        return programmeCode;
    }

    public void setProgrammeCode(final String programmeCode) {
        this.programmeCode = programmeCode;
    }

    public String getSearchByInService() {
        return searchByInService;
    }

    public void setSearchByInService(final String searchByInService) {
        this.searchByInService = searchByInService;
    }

    public ParamService getParamService() {
        return paramService;
    }

    public String getProgrammePlanningItemId() {
        return programmePlanningItemId;
    }

    public void setProgrammePlanningItemId(final String programmePlanningItemId) {
        this.programmePlanningItemId = programmePlanningItemId;
    }

    public ProgrammePlanningItem getPpi() {
        return ppi;
    }

    public void setPpi(final ProgrammePlanningItem ppi) {
        this.ppi = ppi;
    }

    public boolean isCanEdit() {
        return canEdit;
    }

    public void setCanEdit(final boolean canEdit) {
        this.canEdit = canEdit;
    }

    public CategoryService getCategoryService() {
        return categoryService;
    }

    public void setCategoryService(final CategoryService categoryService) {
        this.categoryService = categoryService;
    }

}
